'''
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License") you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http:#www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
'''


#import java.util.concurrent.atomic.AtomicInteger;

#import org.apache.jena.rdf.model.AnonId;
#import org.apache.jena.shared.impl.JenaParameters;

'''
 * System identifier for a blank node.
 * <p>
 * Blank nodes have identity (you can .equals them apart)
 * but no external stable identifier like a URI.
 * <p>
 * Databases need a persistent identifier for blank nodes - BlankNodeId.
 * <p>
 * The equivalent concept for the API is:@link AnonId.
 * Historically, that has been in the org.apache.jena.rdf.model
 * package.
 *
 * <p>This id is guaranteed to be globally unique.</p>
 *
 * @see JenaParameters#disableBNodeUIDGeneration
'''

from abc import ABC
#from multiprocessing import Value
import uuid

class BlankNodeId(ABC):
    # Jena RIOT parsers also generate labels : see LabelToNode. 
    # This has been in RIOT for a long time (Jena2).
    #
    # Jena used to use java.rmi.UID for API unlabeled blank nodes
    # in BlankNodeId() until v3.3.0 with "(new UID()).toString()".

    def __init__(self, id):
        #string
        if id is None:
            self.id = uuid.uuid1()
        else:
            self.id = id

    '''
     * Support for debugging ONLY: global BlankNodeId counter. The intial value is
     * just to make the output look prettier if it has lots (but not lots and
     * lots) of bnodes in it.
    '''
    # param 100000
    # result static AtomicInteger idCount = new
    #idCount = new AtomicInteger(self)
    #idCount = Value('i', 0)

    '''
     * Creates BlankNodeId with a fresh internal id
    '''
    # param 
    # result static BlankNodeId
    # def create(self):
    #     return BlankNodeId()
    

    '''
     * Creates BlankNodeId with the given id
    '''
    # param String id
    # result static BlankNodeId
    @staticmethod
    def create(id):
        if id is None:
            return BlankNodeId(None)
        return BlankNodeId(id)
    

    # protected BlankNodeId():
    #     if (JenaParameters.disableBNodeUIDGeneration)
    #         id = "A" + idCount.getAndIncrement()
    #     else
    #         id = java.util.UUID.randomUUID().toString()
    #

    '''
     * Create a BlankNodeId from the string argument supplied.
     *
     * @param id A string representation of the id to be created.
    '''
    # param String id:
    # def __init__(self, id):
    #     this.id = id
    

    # protected BlankNodeId(BlankNodeId id):
    #     this.id = id.getLabelString()
    

    ##@Override
    # param 
    # result int
    # def hashCode1(self):
    #     #final int
    #     prime = 31
    #     #int
    #     result = 1
    #     tmp = 0 if self.id is None else hash(self.id)
    #     result = prime * result + tmp
    #     return result
    

    '''
     * return a hashcode for this id
     *
     * @return the hash code
    '''
    #@Override
    # param 
    # result int
    def hashCode(self):
        return hash(self.id)
    

    '''
     * Test whether two id's are the same
     *
     * @param other the object to be compared
     * @return true if and only if the two id's are the same
    '''
    #@Override
    # param Object other
    # result boolean
    def equals(self, other):
        return isinstance(other, BlankNodeId) and other.id == self.id
    

    ##@Override
    # param Object obj
    # result boolean
    # def equals1(self, obj):
    #     if (this == obj)
    #         return true
    #     if (obj == null)
    #         return false
    #     if (!(obj instanceof BlankNodeId))
    #         return false
    #     BlankNodeId other = (BlankNodeId) obj
    #     if (id == null):
    #         if (other.id != null)
    #             return false
    #      else if (!id.equals(other.id))
    #         return false
    #     return true
    


    '''
     * return a string representation of the id
     *
     * @return a string representation of the id
    '''
    #@Override
    # param 
    # result String
    def toString(self):
        return self.id
    

    '''
     * Answer the label string of this BlankNodeId. To be used in preference to
     *:@code toString
    '''
    # param 
    # result String
    def getLabelString(self):
        return self.id
    

